"""分页查询使用示例（重构后版本）

演示如何使用新的分页查询功能获取全量药品字典数据。
"""

import logging
from core.db_manager import get_db_session
from model.his.yp1 import Yp1
from sqlmodel import select, func
from fastapi_pagination import Params
from fastapi_pagination.ext.sqlmodel import paginate as sqlmodel_paginate
from config.config_manager import get_hospital_config

# 配置日志
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)


def get_drug_dict_count():
    """获取药品字典总记录数"""
    with get_db_session() as session:
        statement = select(func.count(Yp1.idm))
        result = session.execute(statement).scalar()
    return result or 0


def get_drug_dict(limit=100):
    """基本查询（限制条数）"""
    with get_db_session() as session:
        statement = select(Yp1).order_by(Yp1.ypmc).limit(limit)
        result = session.execute(statement).scalars().all()
    return result


def get_drug_dict_paginated(page_size=1000):
    """分页查询（生成器）"""
    page = 1
    
    while True:
        with get_db_session() as session:
            statement = select(Yp1).order_by(Yp1.ypmc)
            result = sqlmodel_paginate(session, statement, Params(page=page, size=page_size))
            results = result.items
        
        if not results:
            break
            
        yield results
        
        if len(results) < page_size:
            break
            
        page += 1


def get_drug_dict_all(page_size=1000):
    """获取全量数据（一次性返回）"""
    all_results = []
    page = 1
    
    while True:
        with get_db_session() as session:
            statement = select(Yp1).order_by(Yp1.ypmc)
            result = sqlmodel_paginate(session, statement, Params(page=page, size=page_size))
            results = result.items
        
        if not results:
            break
            
        all_results.extend(results)
        
        if len(results) < page_size:
            break
            
        page += 1
    
    return all_results


def get_drug_dict_page(page=1, page_size=None):
    """分页查询（指定页码和每页条数）"""
    if page_size is None:
        hospital_config = get_hospital_config()
        page_size = hospital_config.get("page_size", 1000)
    
    with get_db_session() as session:
        statement = select(Yp1).order_by(Yp1.ypmc)
        result = sqlmodel_paginate(session, statement, Params(page=page, size=page_size))
    
    # 计算分页信息
    total = result.total
    total_pages = result.pages
    has_next = page < total_pages
    has_prev = page > 1
    
    return {
        "success": True,
        "data": result.items,
        "pagination": {
            "current_page": page,
            "page_size": page_size,
            "total_count": total,
            "total_pages": total_pages,
            "has_next": has_next,
            "has_prev": has_prev
        }
    }


def example_basic_query():
    """示例1: 基本查询（限制条数）"""
    logger.info("=== 示例1: 基本查询 ===")
    
    # 查询前100条数据
    drugs = get_drug_dict(limit=100)
    logger.info(f"获取到 {len(drugs)} 条药品数据")
    
    # 显示前3条数据
    for i, drug in enumerate(drugs[:3]):
        logger.info(f"药品 {i+1}: {drug.ypmc} - {drug.ypgg}")


def example_paginated_query():
    """示例2: 分页查询（逐页处理）"""
    logger.info("=== 示例2: 分页查询 ===")
    
    total_count = get_drug_dict_count()
    logger.info(f"药品字典总记录数: {total_count}")
    
    page_count = 0
    total_fetched = 0
    
    # 使用分页查询，每页1000条
    for page_drugs in get_drug_dict_paginated(page_size=1000):
        page_count += 1
        total_fetched += len(page_drugs)
        
        logger.info(f"处理第 {page_count} 页，本页 {len(page_drugs)} 条，累计 {total_fetched} 条")
        
        # 这里可以对每页数据进行处理
        # 例如：数据清洗、格式转换、发送到其他系统等
        
        # 只处理前3页作为示例
        if page_count >= 3:
            logger.info("示例只处理前3页，实际使用中会处理所有页面")
            break
    
    logger.info(f"分页查询完成，总共处理 {page_count} 页，{total_fetched} 条数据")


def example_get_all_data():
    """示例3: 获取全量数据（一次性返回）"""
    logger.info("=== 示例3: 获取全量数据 ===")
    
    # 注意：这种方式会将所有数据加载到内存中，适用于数据量不大的情况
    all_drugs = get_drug_dict_all(page_size=1000)
    logger.info(f"获取全量数据，总共 {len(all_drugs)} 条药品数据")
    
    # 显示前5条数据
    for i, drug in enumerate(all_drugs[:5]):
        logger.info(f"药品 {i+1}: {drug.ypmc} - {drug.ypgg}")


def example_memory_efficient_processing():
    """示例4: 内存高效的数据处理"""
    logger.info("=== 示例4: 内存高效的数据处理 ===")
    
    processed_count = 0
    
    # 使用分页查询，避免一次性加载所有数据到内存
    for page_drugs in get_drug_dict_paginated(page_size=1000):
        # 处理当前页的数据
        for drug in page_drugs:
            # 这里可以进行各种数据处理操作
            # 例如：数据验证、格式转换、发送到API等
            processed_count += 1
            
            # 每处理1000条记录输出一次进度
            if processed_count % 1000 == 0:
                logger.info(f"已处理 {processed_count} 条记录")
        
        # 处理完一页后，可以释放内存
        # 在Python中，当变量超出作用域时，垃圾回收器会自动回收内存
    
    logger.info(f"数据处理完成，总共处理 {processed_count} 条记录")


def example_page_query():
    """示例5: 分页查询（指定页码和每页条数）"""
    logger.info("=== 示例5: 分页查询 ===")
    
    # 获取总记录数
    total_count = get_drug_dict_count()
    logger.info(f"药品字典总记录数: {total_count}")
    
    # 查询第1页，每页5条（用于演示）
    result = get_drug_dict_page(page=1, page_size=5)
    
    if "error" in result:
        logger.error(f"查询失败: {result['error']}")
        return
    
    pagination = result["pagination"]
    data = result["data"]
    
    logger.info(f"分页信息:")
    logger.info(f"  当前页: {pagination['current_page']}")
    logger.info(f"  每页条数: {pagination['page_size']}")
    logger.info(f"  总记录数: {pagination['total_count']}")
    logger.info(f"  总页数: {pagination['total_pages']}")
    logger.info(f"  有下一页: {pagination['has_next']}")
    logger.info(f"  有上一页: {pagination['has_prev']}")
    
    logger.info(f"当前页数据 ({len(data)} 条):")
    for i, drug in enumerate(data):
        logger.info(f"  {i+1}. {drug.ypmc} - {drug.ypgg}")
    
    # 查询第2页
    if pagination['has_next']:
        logger.info("\n查询第2页:")
        result2 = get_drug_dict_page(page=2, page_size=5)
        if "error" not in result2:
            data2 = result2["data"]
            logger.info(f"第2页数据 ({len(data2)} 条):")
            for i, drug in enumerate(data2):
                logger.info(f"  {i+1}. {drug.ypmc} - {drug.ypgg}")


def example_api_usage():
    """示例6: API接口使用说明"""
    logger.info("=== 示例6: API接口使用说明 ===")
    
    logger.info("可用的API接口:")
    logger.info("1. GET /api/his/drug-dict - 获取药品字典（现代化分页）")
    logger.info("2. GET /api/his/drug-dict/count - 获取总记录数")
    logger.info("3. GET /api/his/drug-dict/simple - 简化分页查询")
    logger.info("4. GET /api/his/drug-dict/upload - 上传药品字典到SaaS平台")
    
    logger.info("\n分页查询参数说明:")
    logger.info("- page: 页码，从1开始，默认为1")
    logger.info("- size: 每页条数，不指定则从配置文件读取（默认1000）")
    logger.info("- offset: 偏移量（与page二选一）")
    logger.info("- limit: 限制条数（与size二选一）")
    
    logger.info("\n现代化分页返回格式:")
    logger.info("""
    {
        "items": [...],        // 当前页数据
        "total": 5000,         // 总记录数
        "page": 1,             // 当前页
        "size": 1000,          // 每页条数
        "pages": 5             // 总页数
    }
    """)
    
    logger.info("\n简化分页返回格式:")
    logger.info("""
    {
        "success": true,
        "data": [...],  // 当前页数据
        "pagination": {
            "current_page": 1,      // 当前页
            "page_size": 1000,      // 每页条数
            "total_count": 5000,    // 总记录数
            "total_pages": 5,       // 总页数
            "has_next": true,       // 是否有下一页
            "has_prev": false       // 是否有上一页
        },
        "hospital": "各厂商HIS医院"
    }
    """)


if __name__ == "__main__":
    try:
        # 运行所有示例
        example_basic_query()
        print()
        
        example_paginated_query()
        print()
        
        # 注意：获取全量数据可能会消耗大量内存，请根据实际情况决定是否运行
        # example_get_all_data()
        # print()
        
        example_memory_efficient_processing()
        print()
        
        example_page_query()
        print()
        
        example_api_usage()
        
    except Exception as e:
        logger.error(f"运行示例时发生错误: {e}", exc_info=True)